Linux webm002.cluster126.gra.hosting.ovh.net 5.15.206-ovh-vps-grsec-zfs-classid #1 SMP Fri May 15 02:41:25 UTC 2026 x86_64
/
home
/
ariannadhf
/
www
/
wp-content
/
plugins
/
ninjafirewall
/
lib
/
/home/ariannadhf/www/wp-content/plugins/ninjafirewall/lib/firewall.php
<?php /* +=====================================================================+ | _ _ _ _ _____ _ _ _ | | | \ | (_)_ __ (_) __ _| ___(_)_ __ _____ ____ _| | | | | | \| | | '_ \ | |/ _` | |_ | | '__/ _ \ \ /\ / / _` | | | | | | |\ | | | | || | (_| | _| | | | | __/\ V V / (_| | | | | | |_| \_|_|_| |_|/ |\__,_|_| |_|_| \___| \_/\_/ \__,_|_|_| | | |__/ | | (c) NinTechNet Limited ~ https://nintechnet.com/ | +=====================================================================+ */ if ( strpos($_SERVER['SCRIPT_NAME'], '/nfwlog/') !== FALSE || strpos($_SERVER['SCRIPT_NAME'], '/ninjafirewall/') !== FALSE ) { die('Forbidden'); } if ( defined('NFW_STATUS') ) { return; } if ( defined('WP_CLI') && WP_CLI && PHP_SAPI === 'cli' ) { if (! defined('NFW_UWL') ) { define('NFW_UWL', true); } return; } $nfw_ = []; $nfw_['fw_starttime'] = nfw_fc_metrics('start'); /** * Required classes and constants. */ if ( ! defined('NFWLOG_DEBUG') ) { define('NFWLOG_MEDIUM', 1); define('NFWLOG_HIGH', 2); define('NFWLOG_CRITICAL', 3); define('NFWLOG_POSTDETECT', 4); define('NFWLOG_UPLOAD', 5); define('NFWLOG_INFO', 6); define('NFWLOG_DEBUG', 7); } require_once __DIR__ .'/class-ip.php'; require_once __DIR__ .'/class-firewall-log.php'; /** * Optional NinjaFirewall configuration file. * See https://blog.nintechnet.com/ninjafirewall-wp-edition-the-htninja-configuration-file/ */ if ( @is_file( $nfw_['file'] = $_SERVER['DOCUMENT_ROOT'] .'/.htninja') || @is_file( $nfw_['file'] = dirname( $_SERVER['DOCUMENT_ROOT'] ) .'/.htninja') ) { $nfw_['res'] = @include_once $nfw_['file']; /** * Allow and stop filtering. */ if ( $nfw_['res'] == 'ALLOW') { if (! defined('NFW_UWL') ) { define('NFW_UWL', true ); } nfw_quit( 20 ); return; } /** * Reject immediately. */ if ( $nfw_['res'] == 'BLOCK') { header('HTTP/1.1 403 Forbidden'); header('Status: 403 Forbidden'); header('Pragma: no-cache'); header('Cache-Control: no-cache, no-store, must-revalidate'); header('Expires: 0'); die('403 Forbidden'); } } // Clear warning if there's an open_basedir restriction if ( function_exists('error_clear_last') ) { // PHP 7.0+ error_clear_last(); } $nfw_['wp_content'] = dirname(dirname(dirname( __DIR__ ))); // Check if we have a user-defined log directory // (see "Path to NinjaFirewall's log and cache directory" // at https://blog.nintechnet.com/ninjafirewall-wp-edition-the-htninja-configuration-file/ ) : if ( defined('NFW_LOG_DIR') ) { $nfw_['log_dir'] = NFW_LOG_DIR . '/nfwlog'; } else { $nfw_['log_dir'] = $nfw_['wp_content'] . '/nfwlog'; } if (! is_dir($nfw_['log_dir']) ) { if (! mkdir( $nfw_['log_dir'] . '/cache', 0755, true) ) { define( 'NFW_STATUS', 13 ); return; } } /** * Select whether we want to use PHP or NF (default since v4.8.1) sessions. */ if ( is_file( "{$nfw_['log_dir']}/phpsession" ) ) { require_once __DIR__ .'/class-php-session.php'; } else { if (! defined('NFWSESSION_DIR') ) { /** * NFWSESSION_DIR can be defined in the .htninja. */ define('NFWSESSION_DIR', "{$nfw_['log_dir']}/session" ); } require_once __DIR__ .'/class-nfw-session.php'; } // Get/set PID if ( is_file( "{$nfw_['log_dir']}/cache/.pid" ) ) { define( 'NFW_PID', file_get_contents( "{$nfw_['log_dir']}/cache/.pid" ) ); } // Check if we are connecting over HTTPS nfw_is_https(); if ( strpos($_SERVER['SCRIPT_NAME'], 'wp-login.php' ) !== FALSE ) { nfw_bfd(1); } elseif ( strpos($_SERVER['SCRIPT_NAME'], 'xmlrpc.php' ) !== FALSE ) { nfw_bfd(2); } if (empty ($wp_config)) { $wp_config = dirname($nfw_['wp_content']) . '/wp-config.php'; } // Connection $ret = nfw_connect(); if ( $ret !== true ) { nfw_quit( $ret ); return; } // Fetch options $ret = nfw_get_data( 'nfw_options' ); if ( $ret !== true || empty( $nfw_['nfw_options'] ) ) { nfw_quit( $ret ); return; } /** * Verify and retrieve the user IP address. */ NinjaFirewall_IP::check_ip( ['ac_ip' => 1 ] ); if (! empty($nfw_['nfw_options']['clogs_pubkey']) && isset($_POST['clogs_req']) ) { include_once 'fw_centlog.php'; fw_centlog(); exit; } if ( empty($nfw_['nfw_options']['enabled']) ) { nfw_quit( 20 ); return; } // HTTP response headers if ( (! empty( $nfw_['nfw_options']['response_headers'] ) || ! empty($nfw_['nfw_options']['custom_headers']) ) && function_exists('header_register_callback') ) { if (! empty( $nfw_['nfw_options']['response_headers'] ) ) { define('NFW_RESHEADERS', $nfw_['nfw_options']['response_headers']); if (! empty( $nfw_['nfw_options']['response_headers'][6] ) && ! empty( $nfw_['nfw_options']['csp_frontend_data'] ) ) { define( 'CSP_FRONTEND_DATA', $nfw_['nfw_options']['csp_frontend_data']); } if (! empty( $nfw_['nfw_options']['response_headers'][7] ) && ! empty( $nfw_['nfw_options']['csp_backend_data'] ) ) { define( 'CSP_BACKEND_DATA', $nfw_['nfw_options']['csp_backend_data'] ); } } if (! empty( $nfw_['nfw_options']['custom_headers'] ) ) { define('NFW_CUSTHEADERS', $nfw_['nfw_options']['custom_headers']); } header_register_callback('nfw_response_headers'); } if (! empty($nfw_['nfw_options']['force_ssl']) ) { define('FORCE_SSL_ADMIN', true); } if (! empty($nfw_['nfw_options']['disallow_edit']) ) { define('DISALLOW_FILE_EDIT', true); } if (! empty($nfw_['nfw_options']['disallow_mods']) ) { define('DISALLOW_FILE_MODS', true); } if (! empty($nfw_['nfw_options']['disable_error_handler']) ) { define('WP_DISABLE_FATAL_ERROR_HANDLER', true); } // Superglobals override if (! empty($nfw_['nfw_options']['php_superglobals']) ) { $sgs = [ '_GET', '_POST', '_SESSION', '_COOKIE', '_SERVER', '_FILES', '_ENV', '_REQUEST', 'GLOBALS' ]; foreach( $sgs as $sg ) { if ( isset( $_GET[$sg] ) ) { $nfw_['incidentID'] = NinjaFirewall_log::write( 'Superglobals override attempt', "\$_GET[$sg]: ". serialize( $_GET[$sg] ), NFWLOG_INFO, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); unset( $_GET[$sg] ); } if ( isset( $_POST[$sg] ) ) { $nfw_['incidentID'] = NinjaFirewall_log::write( 'Superglobals override attempt', "\$_POST[$sg]: ". serialize( $_POST[$sg] ), NFWLOG_INFO, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); unset( $_POST[$sg] ); } if ( isset( $_COOKIE[$sg] ) ) { $nfw_['incidentID'] = NinjaFirewall_log::write( 'Superglobals override attempt', "\$_COOKIE[$sg]: ". serialize( $_COOKIE[$sg] ), NFWLOG_INFO, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); unset( $_COOKIE[$sg] ); } } } // We only start a session if users already have a session // cookie because we don't need write access yet $session_name = NinjaFirewall_session::name(); if ( isset( $_COOKIE[ $session_name ] ) ) { NinjaFirewall_session::start(); } if (! empty( NinjaFirewall_session::read('nfw_goodguy') ) ) { // Look for Live Log AJAX request if (! empty( NinjaFirewall_session::read('nfw_livelog') ) && isset( $_POST['livecls'] ) && isset( $_POST['lines'] ) ) { include_once 'fw_livelog.php'; fw_livelog_show(); } // Fetch admin rules $ret = nfw_get_data( 'nfw_rules' ); if ( $ret !== true ) { nfw_quit( $ret ); return; } nfw_check_admin_request(); nfw_quit( 20 ); return; } define('NFW_SWL', 1); if ( is_file($nfw_['log_dir'] .'/cache/livelogrun.php')) { include_once 'fw_livelog.php'; fw_livelog_record(); } if (! empty($nfw_['nfw_options']['php_errors']) ) { @error_reporting(0); @ini_set('display_errors', 0); } if ( empty($nfw_['nfw_options']['allow_local_ip']) && NFW_REMOTE_ADDR_PRIVATE == true ) { nfw_quit(20); return; } if ( NFW_REMOTE_ADDR_PRIVATE == true && strpos( $_SERVER['SCRIPT_NAME'], '/wp-cron.php' ) !== FALSE ) { nfw_quit(20); return; } if ( @$nfw_['nfw_options']['scan_protocol'] == 1 && NFW_IS_HTTPS == true ) { nfw_quit(20); return; } if ( @$nfw_['nfw_options']['scan_protocol'] == 2 && NFW_IS_HTTPS == false ) { nfw_quit(20); return; } /** * File Guard. */ if (! empty( $nfw_['nfw_options']['fg_enable'] ) ) { include_once 'fw_fileguard.php'; fw_fileguard(); } if (! empty($nfw_['nfw_options']['no_host_ip']) && @filter_var(parse_url('http://'.$_SERVER['HTTP_HOST'], PHP_URL_HOST), FILTER_VALIDATE_IP) ) { $nfw_['incidentID'] = NinjaFirewall_log::write( 'HTTP_HOST is an IP', $_SERVER['HTTP_HOST'], NFWLOG_HIGH, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); nfw_block(); } if (! empty($nfw_['nfw_options']['referer_post']) && $_SERVER['REQUEST_METHOD'] == 'POST' && ! isset($_SERVER['HTTP_REFERER']) ) { $nfw_['incidentID'] = NinjaFirewall_log::write( 'POST method without Referer header', $_SERVER['REQUEST_METHOD'], NFWLOG_MEDIUM, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); nfw_block(); } if (! empty($nfw_['nfw_options']['admin_ajax']) && strpos( $_SERVER['SCRIPT_NAME'], 'wp-admin/admin-ajax.php' ) !== FALSE ) { nfw_is_bot( 'admin-ajax.php' ); } if ( strpos($_SERVER['SCRIPT_NAME'], '/xmlrpc.php' ) !== FALSE ) { if (! empty($nfw_['nfw_options']['no_xmlrpc']) ) { $nfw_['incidentID'] = NinjaFirewall_log::write( 'Access to WordPress XML-RPC API', $_SERVER['SCRIPT_NAME'], NFWLOG_HIGH, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); nfw_block(); } if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) { if (! isset( $HTTP_RAW_POST_DATA ) ) { @$HTTP_RAW_POST_DATA = file_get_contents( 'php://input' ); } if (! empty($nfw_['nfw_options']['no_xmlrpc_multi']) ) { if ( @strpos( $HTTP_RAW_POST_DATA, '<methodName>system.multicall</methodName>') !== FALSE ) { $nfw_['incidentID'] = NinjaFirewall_log::write( 'Access to WordPress XML-RPC API (system.multicall method)', $_SERVER['SCRIPT_NAME'], NFWLOG_HIGH, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); nfw_block(); } } if (! empty($nfw_['nfw_options']['no_xmlrpc_pingback']) ) { if ( @strpos( $HTTP_RAW_POST_DATA, '<methodName>pingback.ping</methodName>') !== FALSE ) { $nfw_['incidentID'] = NinjaFirewall_log::write( 'Access to WordPress XML-RPC API (pingback.ping)', $_SERVER['SCRIPT_NAME'], NFWLOG_HIGH, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); nfw_block(); } } } } if (! empty($nfw_['nfw_options']['no_xmlrpc_pingback']) && strpos($_SERVER['HTTP_USER_AGENT'], '; verifying pingback from ') !== FALSE) { $nfw_['incidentID'] = NinjaFirewall_log::write( 'Blocked pingback verification', $_SERVER['HTTP_USER_AGENT'], NFWLOG_HIGH, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); nfw_block(); } // WordPress Aplication Passwords if (! empty($nfw_['nfw_options']['no_appswd']) && strpos( $_SERVER['SCRIPT_NAME'], '/wp-admin/authorize-application.php' ) !== FALSE ) { $nfw_['incidentID'] = NinjaFirewall_log::write( 'Access to WordPress Application Passwords', $_SERVER['SCRIPT_NAME'], NFWLOG_HIGH, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); nfw_block(); } if (! empty($nfw_['nfw_options']['no_post_themes']) && $_SERVER['REQUEST_METHOD'] == 'POST' && strpos($_SERVER['SCRIPT_NAME'], $nfw_['nfw_options']['no_post_themes']) !== FALSE ) { $nfw_['incidentID'] = NinjaFirewall_log::write( 'POST request in the themes folder', $_SERVER['SCRIPT_NAME'], NFWLOG_HIGH, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); nfw_block(); } if (! empty($nfw_['nfw_options']['wp_dir']) && preg_match( '`' . $nfw_['nfw_options']['wp_dir'] . '`', $_SERVER['SCRIPT_NAME']) ) { $nfw_['incidentID'] = NinjaFirewall_log::write( 'Forbidden direct access to PHP script', $_SERVER['SCRIPT_NAME'], NFWLOG_HIGH, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); nfw_block(); } nfw_check_upload(); // Fetch rules $ret = nfw_get_data( 'nfw_rules' ); if ( $ret !== true ) { nfw_quit( $ret ); return; } nfw_check_request( $nfw_['nfw_rules'], $nfw_['nfw_options'] ); if (! empty($nfw_['nfw_options']['get_sanitise']) && ! empty($_GET) ){ $_GET = nfw_sanitise( $_GET, 1, 'GET'); } if (! empty($nfw_['nfw_options']['post_sanitise']) && ! empty($_POST) ){ $_POST = nfw_sanitise( $_POST, 1, 'POST'); } if (! empty($nfw_['nfw_options']['request_sanitise']) && ! empty($_REQUEST) ){ $_REQUEST = nfw_sanitise( $_REQUEST, 1, 'REQUEST'); } if (! empty($nfw_['nfw_options']['cookies_sanitise']) && ! empty($_COOKIE) ) { $_COOKIE = nfw_sanitise( $_COOKIE, 3, 'COOKIE'); } if (! empty($nfw_['nfw_options']['ua_sanitise']) && ! empty($_SERVER['HTTP_USER_AGENT']) ) { $_SERVER['HTTP_USER_AGENT'] = nfw_sanitise( $_SERVER['HTTP_USER_AGENT'], 1, 'HTTP_USER_AGENT'); } if (! empty($nfw_['nfw_options']['referer_sanitise']) && ! empty($_SERVER['HTTP_REFERER']) ) { $_SERVER['HTTP_REFERER'] = nfw_sanitise( $_SERVER['HTTP_REFERER'], 1, 'HTTP_REFERER'); } if (! empty($nfw_['nfw_options']['php_path_i']) && ! empty($_SERVER['PATH_INFO']) ) { $_SERVER['PATH_INFO'] = nfw_sanitise( $_SERVER['PATH_INFO'], 2, 'PATH_INFO'); } if (! empty($nfw_['nfw_options']['php_path_t']) && ! empty($_SERVER['PATH_TRANSLATED']) ) { $_SERVER['PATH_TRANSLATED'] = nfw_sanitise( $_SERVER['PATH_TRANSLATED'], 2, 'PATH_TRANSLATED'); } if (! empty($nfw_['nfw_options']['php_self']) && ! empty($_SERVER['PHP_SELF']) ) { $_SERVER['PHP_SELF'] = nfw_sanitise( $_SERVER['PHP_SELF'], 2, 'PHP_SELF'); } nfw_quit(20); return; // ===================================================================== // Close the SQL link, set the firewall status, clear the $nfw_ array // and close the session before leaving. function nfw_quit( $status ) { global $nfw_; define( 'NFW_STATUS', $status ); if ( isset( $nfw_['mysqli'] ) ) { $nfw_['mysqli']->close(); } $nfw_ = []; } // ===================================================================== // Connect to the DB. function nfw_connect() { global $nfw_, $wp_config; // WPWAF mode? if ( defined('NFW_WPWAF') && NFW_WPWAF == 2 ) { $nfw_['wp_waf'] = 2; return true; } // Check if we have a SQL link that was defined in the .htninja. // See "Giving NinjaFirewall a MySQLi link identifier" // at https://blog.nintechnet.com/ninjafirewall-wp-edition-the-htninja-configuration-file/ if (! empty( $GLOBALS['nfw_mysqli'] ) && ! empty( $GLOBALS['nfw_table_prefix'] ) ) { $nfw_['mysqli'] = $GLOBALS['nfw_mysqli']; $nfw_['table_prefix'] = $GLOBALS['nfw_table_prefix']; return true; } // DB if (! is_file( $wp_config ) ) { if (! @is_file( $wp_config = dirname( dirname($nfw_['wp_content']) ) . '/wp-config.php') ) { return 1; } } if (! $nfw_['fh'] = fopen($wp_config, 'r') ) { return 2; } // Potential SQL flags $nfw_['MYSQL_CLIENT_FLAGS'] = 0; while (! feof($nfw_['fh'])) { $nfw_['line'] = fgets($nfw_['fh']); if ( preg_match('/^\s*define\s*\(\s*[\'"]DB_NAME[\'"]\s*,\s*[\'"](.+?)[\'"]/', $nfw_['line'], $nfw_['match']) ) { $nfw_['DB_NAME'] = $nfw_['match'][1]; } elseif ( preg_match('/^\s*define\s*\(\s*[\'"]DB_USER[\'"]\s*,\s*[\'"](.+?)[\'"]/', $nfw_['line'], $nfw_['match']) ) { $nfw_['DB_USER'] = $nfw_['match'][1]; } elseif ( preg_match('/^\s*define\s*\(\s*[\'"]DB_PASSWORD[\'"]\s*,\s*([\'"])(.+?)\1\s*\);/', $nfw_['line'], $nfw_['match']) ) { $nfw_['DB_PASSWORD'] = str_replace( '\\'.$nfw_['match'][1], $nfw_['match'][1], $nfw_['match'][2] ); if ( $nfw_['match'][1] == '"' ) { $nfw_['DB_PASSWORD'] = str_replace( '\$', '$', $nfw_['DB_PASSWORD'] ); } } elseif ( preg_match('/^\s*define\s*\(\s*[\'"]DB_HOST[\'"]\s*,\s*[\'"](.+?)[\'"]/', $nfw_['line'], $nfw_['match']) ) { $nfw_['DB_HOST'] = $nfw_['match'][1]; } elseif ( preg_match('/^\s*\$table_prefix\s*=\s*[\'"](.*?)[\'"]/', $nfw_['line'], $nfw_['match']) ) { $nfw_['table_prefix'] = $nfw_['match'][1]; } elseif ( preg_match('/^\s*define\s*\(\s*[\'"]MYSQL_CLIENT_FLAGS[\'"]\s*,\s*(.+?)\s*\)/', $nfw_['line'], $nfw_['match']) ) { if ( empty( $nfw_['MYSQL_CLIENT_FLAGS'] ) ) { $available_flags = [ 'MYSQLI_CLIENT_COMPRESS' => MYSQLI_CLIENT_COMPRESS, 'MYSQLI_CLIENT_FOUND_ROWS' => MYSQLI_CLIENT_FOUND_ROWS, 'MYSQLI_CLIENT_IGNORE_SPACE' => MYSQLI_CLIENT_IGNORE_SPACE, 'MYSQLI_CLIENT_INTERACTIVE' => MYSQLI_CLIENT_INTERACTIVE, 'MYSQLI_CLIENT_SSL' => MYSQLI_CLIENT_SSL, 'MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT' => MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT ]; // There could be one or more flags, e.g., 'MYSQLI_CLIENT_SSL | MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT' $tmp_flags = explode( '|', $nfw_['match'][1] ); foreach( $tmp_flags as $tmp_flag ) { $tmp_flag = trim( $tmp_flag ); if ( isset( $available_flags[$tmp_flag] ) ) { $nfw_['MYSQL_CLIENT_FLAGS'] += $available_flags[$tmp_flag]; } } } } } fclose($nfw_['fh']); unset($wp_config); if (! isset($nfw_['DB_NAME']) || ! isset($nfw_['DB_USER']) || ! isset($nfw_['DB_PASSWORD']) || ! isset($nfw_['DB_HOST']) || ! isset($nfw_['table_prefix']) ) { return 3; } /** * Parse hostname/port and socket. */ require_once __DIR__ .'/class-nfw-database.php'; $host_data = NinjaFirewall_fwdatabase::parse_db_host( $nfw_['DB_HOST'] ); if ( $host_data ) { list( $nfw_['DB_HOST'], $nfw_['port'], $nfw_['socket'] ) = $host_data; } // Make sure mysqli extension is loaded if (! function_exists( 'mysqli_real_connect' ) ) { return 14; } @$nfw_['mysqli'] = mysqli_init(); @mysqli_real_connect( $nfw_['mysqli'], $nfw_['DB_HOST'], $nfw_['DB_USER'], $nfw_['DB_PASSWORD'], $nfw_['DB_NAME'], $nfw_['port'], $nfw_['socket'], $nfw_['MYSQL_CLIENT_FLAGS'] ); if ($nfw_['mysqli']->connect_error) { return 4; } return true; } // ===================================================================== // Fetch rules and options. function nfw_get_data( $what ) { global $nfw_; if ( $what != 'nfw_rules' ) { $what = 'nfw_options'; } // WP API if ( isset( $nfw_['wp_waf'] ) && $nfw_['wp_waf'] == 2 ) { if ( is_multisite() ) { $nfw_[ $what ] = get_site_option( $what ); } else { $nfw_[ $what ] = get_option( $what ); } return true; // DB } else { // Rules if ( $what == 'nfw_rules' ) { if (! $nfw_['result'] = @$nfw_['mysqli']->query('SELECT * FROM `' . $nfw_['mysqli']->real_escape_string($nfw_['table_prefix']) . "options` WHERE `option_name` = 'nfw_rules'") ) { return 7; } if (! $nfw_['rules'] = @$nfw_['result']->fetch_object() ) { return 8; } if (! $nfw_['nfw_rules'] = @unserialize( $nfw_['rules']->option_value ) ) { return 12; } // Options } else { /** * Since PHP 8.1, MySQLi extension throws an Exception on errors */ try { $nfw_['result'] = @$nfw_['mysqli']->query('SELECT * FROM `' . $nfw_['mysqli']->real_escape_string( $nfw_['table_prefix'] ) . "options` WHERE `option_name` = 'nfw_options'" ); } catch ( Exception $e ) { /** * Maybe this is an old multisite install where the main site * options table is named 'wp_1_options' instead of 'wp_options' */ try { $nfw_['result'] = @$nfw_['mysqli']->query('SELECT * FROM `' . $nfw_['mysqli']->real_escape_string( $nfw_['table_prefix'] ) . "1_options` WHERE `option_name` = 'nfw_options'" ); } catch ( Exception $e ) { return 5; } /** * Change the table prefix to match 'wp_1_options' */ $nfw_['table_prefix'] = "{$nfw_['table_prefix']}1_"; } if (! $nfw_['options'] = @$nfw_['result']->fetch_object() ) { return 6; } if (! $nfw_['nfw_options'] = @unserialize( $nfw_['options']->option_value ) ) { return 11; } } // Make sure we have something or return an error if ( $what == 'nfw_rules' && ! isset( $nfw_['nfw_rules']['1'] ) ) { return 16; } elseif ( $what == 'nfw_options' && ! isset( $nfw_['nfw_options']['enabled'] ) ) { return 15; } // All good return true; } } // ===================================================================== // Check for HTTPS. function nfw_is_https() { // Can be defined in the .htninja: if ( defined('NFW_IS_HTTPS') ) { return; } if ( ( isset( $_SERVER['SERVER_PORT'] ) && $_SERVER['SERVER_PORT'] == 443 ) || ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') || ( isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] !== 'off' ) ) { define('NFW_IS_HTTPS', true); } else { define('NFW_IS_HTTPS', false); } } // ===================================================================== function nfw_check_upload() { if ( defined('NFW_STATUS') ) { return; } global $nfw_; $f_uploaded = []; $f_uploaded = nfw_fetch_uploads(); $tmp = ''; if ( empty($nfw_['nfw_options']['uploads']) ) { $tmp = ''; foreach ($f_uploaded as $key => $value) { if (! $f_uploaded[$key]['name']) { continue; } if ( empty( $f_uploaded[$key]['size'] ) ) { $f_uploaded[$key]['size'] = 0; } $tmp .= $f_uploaded[$key]['name'] . ' (' . number_format($f_uploaded[$key]['size']) . ' bytes) '; } if ( $tmp ) { $nfw_['incidentID'] = NinjaFirewall_log::write( 'Blocked file upload attempt', rtrim( $tmp, ' '), NFWLOG_CRITICAL, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); nfw_block(); } } else { foreach ($f_uploaded as $key => $value) { if (! $f_uploaded[$key]['name']) { continue; } if ( empty( $f_uploaded[$key]['size'] ) ) { $f_uploaded[$key]['size'] = 0; } if ( $f_uploaded[$key]['size'] > 67 && $f_uploaded[$key]['size'] < 129 ) { $data = file_get_contents( $f_uploaded[$key]['tmp_name'] ); if ( preg_match('`^X5O!P%@AP' . '\[4\\\PZX54\(P\^\)7CC\)7}\$EIC' . 'AR-STANDARD-ANTIVI' . 'RUS-TEST-FILE!\$H' . '\+H\*' . '[\x09\x10\x13\x20\x1A]*`', $data) ) { $nfw_['incidentID'] = NinjaFirewall_log::write( 'EICAR Standard Anti-Virus Test File blocked', $f_uploaded[$key]['name'] .' ('. number_format($f_uploaded[$key]['size']) .' bytes)', NFWLOG_CRITICAL, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); nfw_block(); } } if (! defined('NFW_NO_MIMECHECK') && isset( $f_uploaded[$key]['type'] ) && ! preg_match('/\/.*\bphp\d?\b/i', $f_uploaded[$key]['type']) && preg_match('/\.ph(?:p([34x7]|5\d?)?|t(ml)?)(?:\.|$)/', $f_uploaded[$key]['name']) ) { $nfw_['incidentID'] = NinjaFirewall_log::write( 'Blocked file upload attempt (MIME-type mismatch)', "{$f_uploaded[$key]['name']} != {$f_uploaded[$key]['type']}", NFWLOG_CRITICAL, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); nfw_block(); } if (! empty($nfw_['nfw_options']['sanitise_fn']) ) { if ( empty( $nfw_['nfw_options']['substitute'] ) ) { $nfw_['nfw_options']['substitute'] = 'X'; } $tmp = ''; $f_uploaded_name = $f_uploaded[$key]['name']; $f_uploaded[$key]['name'] = preg_replace('/[^\w\.\-]/i', $nfw_['nfw_options']['substitute'], $f_uploaded[$key]['name'], -1, $count); // Sanitize double (or more) extensions (e.g., foo.php.gif => foo.php_.gif) $ret = []; $ret = nfw_sanitize_extensions( $f_uploaded[$key]['name'], $nfw_['nfw_options']['substitute'] ); if (! empty( $ret['count'] ) ) { $count += $ret['count']; $f_uploaded[$key]['name'] = $ret['name']; } if ($count) { $tmp = ' (sanitising '. $count . ' char. from filename)'; $_FILES = nfw_sanitize_filename( $_FILES, $f_uploaded_name, $f_uploaded[$key]['name'] ); } } if (! isset( $f_uploaded[$key]['size'] ) ) { $size = 'n/a'; } else { $size = number_format( $f_uploaded[$key]['size'] ); } $nfw_['incidentID'] = NinjaFirewall_log::write( 'File upload detected, no action taken' . $tmp , "{$f_uploaded[$key]['name']} ($size bytes)", NFWLOG_UPLOAD, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); } } } // ===================================================================== function nfw_fetch_uploads() { global $file_buffer, $upload_array, $prop_key; $upload_array = []; foreach( $_FILES as $f_key => $f_value ) { foreach( $f_value as $prop_key => $prop_value ) { // Fetch all but 'error': if (! in_array( $prop_key, ['name', 'type', 'tmp_name', 'size'] ) ) { continue; } $file_buffer = $f_key; if ( is_array( $_FILES[$f_key][$prop_key] ) ) { nfw_recursive_upload( $_FILES[$f_key][$prop_key] ); } else { if (! empty( $_FILES[$f_key][$prop_key] ) ) { $upload_array[$f_key][$prop_key] = $_FILES[$f_key][$prop_key]; } } } } return $upload_array; } // ===================================================================== function nfw_recursive_upload( $data ) { global $file_buffer, $upload_array, $prop_key; foreach( $data as $data_key => $data_value ) { if ( is_array( $data_value ) ) { $file_buffer .= "_{$data_key}"; nfw_recursive_upload( $data_value ); } else { if ( empty( $data_value ) ) { continue; } $upload_array["{$file_buffer}_{$data_key}"][$prop_key] = $data_value; } } } // ===================================================================== function nfw_sanitize_filename( $array, $key, $value ) { array_walk_recursive( $array, function( &$v, $k ) use ( $key, $value ) { if (! empty( $v ) && $v == $key ) { $v = $value; } } ); return $array; } function nfw_sanitize_extensions( $filename, $subs ) { $ret = []; $ret['count'] = 0; $parts = explode( '.', $filename ); $ret['name'] = array_shift( $parts ); $extension = array_pop( $parts ); foreach ( $parts as $part ) { if (! empty( $part ) ) { $ret['name'] .= ".{$part}{$subs}"; ++$ret['count']; } } if ( $extension ) { $ret['name'] .= ".{$extension}"; } return $ret; } // ===================================================================== function nfw_check_admin_request() { global $nfw_; if ( isset( $nfw_['nfw_rules']['999'] ) ) { $nfw_['adm_rules'] = []; foreach ( $nfw_['nfw_rules']['999'] as $key => $value ) { if ( empty( $nfw_['nfw_rules'][$key]['ena'] ) ) { continue; } $nfw_['adm_rules'][$key] = $nfw_['nfw_rules'][$key]; } if (! empty( $nfw_['adm_rules'] ) ) { nfw_check_request( $nfw_['adm_rules'], $nfw_['nfw_options'] ); } } } // ===================================================================== function nfw_check_request( $nfw_rules, $nfw_options ) { if ( defined('NFW_STATUS') ) { return; } global $nfw_, $HTTP_RAW_POST_DATA; foreach ( $nfw_rules as $id => $rules ) { if ( empty( $rules['ena']) ) { continue; } $wherelist = explode('|', $rules['cha'][1]['whe']); foreach ($wherelist as $where) { if ( nfw_disabled_scan( $where, $nfw_options ) ) { continue; } // ================================================================= if ( $where == 'RAW' ) { if (! isset( $HTTP_RAW_POST_DATA ) ) { @$HTTP_RAW_POST_DATA = file_get_contents( 'php://input' ); } if ( nfw_matching( 'RAW', $_SERVER['REQUEST_METHOD'], $nfw_rules, $rules, 1, $id, $nfw_options, $HTTP_RAW_POST_DATA ) ) { nfw_check_subrule( 'RAW', $_SERVER['REQUEST_METHOD'], $nfw_rules, $nfw_options, $rules, $id ); } continue; } // ================================================================= if ( $where == 'POST' || $where == 'GET' || $where == 'COOKIE' || $where == 'SERVER' || $where == 'REQUEST' || $where == 'FILES' || $where == 'SESSION' ) { if (! isset( $GLOBALS['_'. $where ] ) ) { continue; } foreach ($GLOBALS['_' . $where] as $key => $val) { if ( nfw_matching( $where, $key, $nfw_rules, $rules, 1, $id, $nfw_options ) ) { nfw_check_subrule( $where, $key, $nfw_rules, $nfw_options, $rules, $id ); } } continue; } // ================================================================= if ( isset( $_SERVER[$where] ) ) { if ( nfw_matching( 'SERVER', $where, $nfw_rules, $rules, 1, $id, $nfw_options ) ) { nfw_check_subrule( 'SERVER', $where, $nfw_rules, $nfw_options, $rules, $id ); } continue; } // ================================================================= $w = explode(':', $where); // Look for temp hash if ( isset( $rules['cha'][1]['tmp'] ) && isset( $w[1] ) ) { $w[1] = @nfw_check_temp_hash( $w[0], $w[1] ); } if ( empty($w[1]) || ! isset( $GLOBALS['_'.$w[0]][$w[1]] ) || nfw_disabled_scan( $w[0], $nfw_options ) ) { continue; } if ( nfw_matching( $w[0], $w[1], $nfw_rules, $rules, 1, $id, $nfw_options ) ) { nfw_check_subrule( $w[0], $w[1], $nfw_rules, $nfw_options, $rules, $id ); } // ================================================================= } } } // ===================================================================== // Check hash found in a temporary rule (used for hotfix, 0-day etc). function nfw_check_temp_hash( $where, $what ) { global $nfw_; if (is_array( $GLOBALS["_{$where}"] ) && ! empty( $GLOBALS["_{$where}"] ) ) { // Loop foreach( $GLOBALS["_{$where}"] as $key => $value ) { if ( is_string( $key ) ) { // Search in the cache if ( isset( $nfw_['hash'][$key] ) ) { if ( $nfw_['hash'][$key] == $what ) { return $key; } } else { // Save it to the cache $nfw_['hash'][$key] = md5( substr_replace( $key, 'nfw', 2, 0 ) ); if ( $nfw_['hash'][$key] == $what ) { return $key; } } } } } return $what; } // ===================================================================== function nfw_check_subrule( $w0, $w1, $nfw_rules, $nfw_options, $rules, $id ) { if ( isset( $rules['cha'][1]['cap'] ) ) { nfw_matching( $w0, $w1, $nfw_rules, $rules, 2, $id, $nfw_options ); } else { $w = explode(':', $rules['cha'][2]['whe']); if (! isset( $w[1] ) ) { if ( $w[0] == 'RAW' ) { if ( nfw_disabled_scan( 'POST', $nfw_options) && $_SERVER['REQUEST_METHOD'] == 'POST' ) { return; } global $HTTP_RAW_POST_DATA; if (! isset( $HTTP_RAW_POST_DATA ) ) { @$HTTP_RAW_POST_DATA = file_get_contents( 'php://input' ); } nfw_matching( $_SERVER['REQUEST_METHOD'], 'RAW', $nfw_rules, $rules, 2, $id, $nfw_options, $HTTP_RAW_POST_DATA ); return; } $w[2] = $w[1] = $w[0]; $w[0] = 'SERVER'; } else { $w[2] = null; // Look for temp hash if ( isset( $rules['cha'][2]['tmp'] ) ) { $w[1] = @nfw_check_temp_hash( $w[0], $w[1] ); } } if (! isset( $GLOBALS['_'.$w[0]][$w[1]] ) ) { return; } if ( nfw_disabled_scan( $w[0], $nfw_options, $w[2] ) ) { return; } else { nfw_matching( $w[0], $w[1], $nfw_rules, $rules, 2, $id, $nfw_options); } } } // ===================================================================== function nfw_disabled_scan( $where, $nfw_options, $extra = null ) { if ( $extra ) { $where = $extra; } if ( $where == 'POST' && empty($nfw_options['post_scan']) || $where == 'GET' && empty($nfw_options['get_scan']) || $where == 'COOKIE' && empty($nfw_options['cookies_scan']) || $where == 'HTTP_USER_AGENT' && empty($nfw_options['ua_scan']) || $where == 'HTTP_REFERER' && empty($nfw_options['referer_scan']) ) { return 1; } return 0; } // ===================================================================== function nfw_matching( $where, $key, $nfw_rules, $rules, $subid, $id, $nfw_options, $RAW_POST = null ) { global $nfw_; if ( isset( $RAW_POST ) ) { $val = $RAW_POST; } else { $val = $GLOBALS['_'.$where][$key]; } /** * Check if the user has the required capability, if any. */ if ( isset( $rules['cpb'] ) ) { $allcaps = NinjaFirewall_session::read('allcaps'); if (! empty( $allcaps ) ) { $caps = explode('|', $rules['cpb'] ); foreach( $caps as $cap ) { if ( isset( $allcaps[$cap] ) ) { return 0; } } } } if ( is_array($val) ) { if ( isset( $nfw_['flattened'][$where][$key] ) ) { $val = $nfw_['flattened'][$where][$key]; } else { $val = nfw_flatten( ' ', $val ); $nfw_['flattened'][$where][$key] = $val; } } if ( $where == 'POST' && ! empty($nfw_options['post_b64']) && ! isset($nfw_['b64'][$where][$key]) && $val ) { nfw_check_b64($key, $val); $nfw_['b64'][$where][$key] = 1; } $transform = 1; // NF < 4.1.1: if ( isset( $rules['cha'][$subid]['exe'] ) ) { $transform = 0; if ( function_exists( $rules['cha'][$subid]['exe'] ) ) { $val = @$rules['cha'][$subid]['exe']( $val ); } } // NF >= 4.1.1: if ( isset( $rules['cha'][$subid]['exm'] ) ) { $transform = 0; $exe = explode( '|', $rules['cha'][$subid]['exm'] ); foreach ( $exe as $f ) { if (! function_exists( $f ) ) { break; } $val = @$f( $val ); } } $t = ''; if ( isset( $rules['cha'][$subid]['nor'] ) ) { $t .= 'N'; if ( isset( $nfw_[$t][$where][$key] ) && $transform ) { $val = $nfw_[$t][$where][$key]; } else { $val = nfw_normalize( $val, $nfw_rules ); if ( $transform ) { $nfw_[$t][$where][$key] = $val; } } } if ( isset( $rules['cha'][$subid]['tra'] ) ) { $t .= 'T' . $rules['cha'][$subid]['tra']; if ( isset( $nfw_[$t][$where][$key] ) && $transform ) { $val = $nfw_[$t][$where][$key]; } else { $val = nfw_transform_string( $val, $rules['cha'][$subid]['tra'] ); if ( $transform ) { $nfw_[$t][$where][$key] = $val; } } } if ( empty( $rules['cha'][$subid]['noc']) ) { $t .= 'C'; if ( isset( $nfw_[$t][$where][$key] ) && $transform ) { $val = $nfw_[$t][$where][$key]; } else { $val = nfw_compress_string( $val ); if ( $transform ) { $nfw_[$t][$where][$key] = $val; } } } if ( nfw_operator( $val, $rules['cha'][$subid]['wha'], $rules['cha'][$subid]['ope'] ) ) { if ( isset( $rules['cha'][$subid+1]) ) { return 1; } else { if ( isset( $nfw_['flattened'][$where][$key] ) ) { $nfw_['incidentID'] = NinjaFirewall_log::write( $rules['why'], "$where:$key = {$nfw_['flattened'][$where][$key]}", $rules['lev'], $id, $nfw_['nfw_options'], $nfw_['log_dir'] ); } elseif ( isset( $RAW_POST ) ) { $nfw_['incidentID'] = NinjaFirewall_log::write( $rules['why'], "$where:$key = $RAW_POST", $rules['lev'], $id, $nfw_['nfw_options'], $nfw_['log_dir'] ); } else { $nfw_['incidentID'] = NinjaFirewall_log::write( $rules['why'], "$where:$key = {$GLOBALS['_'.$where][$key]}", $rules['lev'], $id, $nfw_['nfw_options'], $nfw_['log_dir'] ); } nfw_block(); } } return 0; } // ===================================================================== function nfw_operator( $val, $what, $op ) { if (! $val ) { return false; } if ( $op == 2 ) { if ( $val != $what ) { return true; } } elseif ( $op == 3 ) { if ( strpos($val, $what) !== FALSE ) { return true; } } elseif ( $op == 4 ) { if ( stripos($val, $what) !== FALSE ) { return true; } } elseif ( $op == 5 ) { if ( preg_match("`$what`", $val ) ) { return true; } } elseif ( $op == 6 ) { if (! preg_match("`$what`", $val) ) { return true; } } elseif ( $op == 7 ) { return true; } elseif ( $op == 8 ) { if ( strpos($val, $what) === FALSE ) { return true; } } elseif ( $op == 9 ) { if ( stripos($val, $what) === FALSE ) { return true; } } else { if ( $val == $what ) { return true; } } } // ===================================================================== function nfw_normalize( $string, $nfw_rules ) { if ( empty( $string ) ) { return; } $norm = rawurldecode( $string ); if ( strpos( $norm, '%' ) !== false ) { $norm = rawurldecode( $norm ); } if (! $norm ) { return $string; } if ( preg_match('/&(?:#x(?:00)*[0-9a-f]{2}|#0*[12]?[0-9]{2}|amp|[lg]t|nbsp|quot)(?!;|\d)/i', $norm) ) { $norm = preg_replace('/&(#x(?:00)*[0-9a-f]{2}|#0*[12]?[0-9]{2}|amp|[lg]t|nbsp|quot)(?!;|\d)/i', '&\1;', $norm); if (! $norm ) { return $string; } } if ( preg_match('/\\\(?:0?[4-9][0-9]|1[0-7][0-9])/', $norm) ) { $norm = preg_replace_callback('/\\\(0?[4-9][0-9]|1[0-7][0-9])/', 'nfw_oct2ascii', $norm); if (! $norm ) { return $string; } } if ( preg_match('/\\\x[a-f0-9]{2}/i', $norm) ) { $norm = preg_replace_callback('/\\\x([a-f0-9]{2})/i', 'nfw_hex2ascii', $norm); if (! $norm ) { return $string; } } $norm = nfw_html_decode( $norm ); if (! $norm ) { return $string; } if ( preg_match('/&#x?[0-9a-f]+;/i', $norm) ) { $norm = preg_replace('/(&#x?[0-9a-f]+;)/i', '', $norm); if (! $norm ) { return $string; } } if ( preg_match( '/(?:%|\\\)u(?:[0-9a-f]{4}|\{0*[0-9a-f]{2}\})/i', $norm ) ) { $norm = preg_replace_callback('/(?:%|\\\)u(?:([0-9a-f]{4})|\{0*([0-9a-f]{2})\})/i', 'nfw_udecode', $norm); if (! $norm ) { return $string; } } if ( empty( $nfw_rules[2]['ena'] ) ) { $norm = preg_replace('/\x0|%00/', '', $norm); if (! $norm ) { return $string; } } return $norm; } // ===================================================================== function nfw_html_decode( $norm ) { global $nfw_; $nfw_['entity_in'] = array ( '	','
','!','"','"','#','$', '%','&','&',''','(',')','*', '*','+',',','.','/',':',';', '<','<','=','>','>','?','@','[', '[','\',']',']','^','_','`', '`','{','{','|','|','|', '}','}',' ',' ','<⃒','>⃒',"\xa0" ); $nfw_['entity_out'] = array ( '','','!','"','"','#','$','%','&','&',"'",'(',')','*','*','+',',','.','/', ':',';','<','<','=','>','>','?','@','[','[','\\',']',']','^','_','`','`', '{','{','|','|','|','}','}',' ',' ','','',' ' ); $normout = str_replace( $nfw_['entity_in'], $nfw_['entity_out'], $norm); $normout = html_entity_decode( $normout, ENT_QUOTES, 'UTF-8' ); return $normout; } // ===================================================================== function nfw_compress_string( $string, $where = null ) { if (! $string ) { return; } if ( $where == 1 ) { $replace = ' '; } else { $replace = ''; } $string = str_replace( ["\x09", "\x0a","\x0b", "\x0c", "\x0d"], $replace, $string); $string = trim ( preg_replace('/\x20{2,}/', ' ', $string) ); return $string; } // ===================================================================== function nfw_transform_string( $string, $where ) { if (! $string ) { return; } if ( $where == 1 ) { $norm = trim( preg_replace_callback('((^([^a-z/&|#]*)|([\'"])(?:\\\\.|[^\n\3\\\\])*?\3|(?:[0-9a-z_$]+)|.)'. '(?:\s|--[^\n]*+\n|/\*(?:[^*!]|\*(?!/))*+\*/)*'. '(?:(?:\#|--(?:[\x00-\x20\x7f]|$)|/\*$)[^\n]*+\n|/\*!(?:\d{5})?|\*/|/\*(?:[^*!]|\*(?!/))*+\*/)*)si', 'nfw_delcomments1', $string . "\n") ); $norm = preg_replace('/[\'"]\x20*\+?\x20*[\'"]/', '', $norm); $norm = strtolower( str_replace( ['+', "'", '"', "(", ')', '`', ',', ';'], ' ', $norm) ); } elseif ( $where == 2 ) { $norm = trim( preg_replace_callback('((^|([\'"])(?:\\\\.|[^\n\2\\\\])*?\2|(?:[0-9a-z_$]+)|.)'. '(?://[^\n]*+\n|/\*(?:[^*]|\*(?!/))*+\*/)*)si', 'nfw_delcomments2', $string . "\n") ); $norm = preg_replace( ['/[\n\r\t\f\v]/', '`/\*\s*\*/`', '/[\'"`]\x20*[+.]?\x20*[\'"`]/'], ['', ' ', ''], $norm ); } elseif ( $where == 3 ) { $norm = preg_replace( ['`([\\\"\'^]|\$\w+)`', '`([,;]|\s+)`'], ['', ' '], $string ); $norm = preg_replace( ['`/(\./)+`','`/{2,}`', '`/(.+?)/\.\./\1\b`', '`\n`', '`\\\`'], ['/', '/', '/\1', '', ''], $norm ); } return $norm; } // ===================================================================== function nfw_delcomments1 ( $match ) { if (! empty($match[2]) ) { return ' '; } if ( $match[0] != $match[1] ) { return $match[1]. ' '; } return $match[1]; } function nfw_delcomments2 ( $match ) { if ( $match[0] != $match[1] ) { return $match[1]. ' '; } return $match[1]; } // ===================================================================== 2023-05-16 function nfw_udecode( $match ) { if ( isset( $match[2] ) ) { return @json_decode('"\\u00'.$match[2].'"'); } return @json_decode('"\\u'.$match[1].'"'); } // ===================================================================== 2023-05-16 function nfw_oct2ascii( $match ) { return chr( octdec( $match[1] ) ); } // ===================================================================== 2023-05-16 function nfw_hex2ascii( $match ) { return chr( hexdec( $match[1] ) ); } // ===================================================================== 2023-05-16 // Flatten an array. function nfw_flatten( $glue, $pieces ) { if ( defined('NFW_STATUS') ) { return; } $ret = []; foreach ( $pieces as $r_pieces ) { if ( is_array( $r_pieces ) ) { $ret[] = nfw_flatten( $glue, $r_pieces ); } else { if (! empty( $r_pieces ) ) { $ret[] = $r_pieces; } } } return implode( $glue, $ret ); } // ===================================================================== function nfw_check_b64( $key, $string ) { if ( defined('NFW_STATUS') || strlen( $string ) < 4 ) { return; } global $nfw_; $whitelist = [ 'fpd_print_order', // Fancy Product Designer 'g-recaptcha-response' // reCAPTCHA ]; if ( in_array( $key, $whitelist ) ) { return; } $decoded = base64_decode( $string ); if ( strlen($decoded) < 4 ) { return; } if ( preg_match( '`\b(?:\$?_(COOKIE|ENV|FILES|(?:GE|POS|REQUES)T|SE(RVER|SSION))|HTTP_(?:(?:POST|GET)_VARS|RAW_POST_DATA)|GLOBALS)\s*[=\[)]|\b(?i:array_map|assert|base64_(?:de|en)code|chmod|curl_exec|(?:ex|im)plode|error_reporting|eval|file(?:_get_contents)?|f(?:open|write|close)|fsockopen|function_exists|gzinflate|md5|move_uploaded_file|ob_start|passthru|[ep]reg_replace|phpinfo|stripslashes|strrev|(?:shell_)?exec|substr|system|unlink)\s*\(|[\s;]echo\s*[\'"]|<(?i:applet|embed|i?frame(?:set)?|marquee|object|script)\b|\W\$\{\s*[\'"]\w+[\'"]|<\?(?i:php|=)\s|(?i:(?:\b|\d)select\b.+?from\b.+?(?:\b|\d)where|(?:\b|\d)insert\b.+?into\b|(?:\b|\d)union\b.+?(?:\b|\d)select\b|(?:\b|\d)update\b.+?(?:\b|\d)set\b)|^.{0,25}[;{}]?\b[OC]:\d+:"[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*":\d+:{.*?}`', $decoded ) ) { // JetPack if ( $key === 'args' && ! defined('NFW_WPWAF') && preg_match( '/^{"query":"SELECT/', $decoded ) && strpos($_SERVER['SCRIPT_NAME'], '/jetpack-temp/jp-helper-') !== FALSE ) { return; } $nfw_['incidentID'] = NinjaFirewall_log::write( 'BASE64-encoded injection', "POST:$key = $string", NFWLOG_CRITICAL, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); nfw_block(); } } // ===================================================================== function nfw_sanitise( $str, $how, $msg ) { if ( defined('NFW_STATUS') ) { return; } if ( empty($str) ) { return $str; } global $nfw_; if (is_string($str) ) { if ($how == 1) { // Full WAF if (! empty( $nfw_['mysqli'] ) ) { $str2 = $nfw_['mysqli']->real_escape_string($str); // WP WAF } else { global $wpdb; $str2 = @$wpdb->_real_escape($str); } $str2 = str_replace( ['`', '<', '>'], ['\\`', '<', '>'], $str2); if ( $msg == 'GET' && strpos( $str2, '/') !== false ) { $str2 = str_replace( ['*', '?'], ['\*', '\?'], $str2 ); } } elseif ($how == 2) { $str2 = str_replace( ['\\', "'", '"', "\x0d", "\x0a", "\x00", "\x1a", '`', '<', '>'], ['\\\\', "\\'", '\\"', '-', '-', '-', '-', '\\`', '<', '>'], $str); } else { $str2 = str_replace( ['\\', "'", "\x00", "\x1a", '`', '<'], ['\\\\', "\\'", '-', '-', '\\`', '<'], $str); } if (! empty($nfw_['nfw_options']['debug']) ) { if ($str2 != $str) { $nfw_['incidentID'] = NinjaFirewall_log::write( 'Sanitising user input', "$msg: $str", NFWLOG_DEBUG, 0, $nfw_['nfw_options'], $nfw_['log_dir'] // '7' for debugging mode only ); } return $str; } if ($str2 != $str) { $nfw_['incidentID'] = NinjaFirewall_log::write( 'Sanitising user input', "$msg: $str", NFWLOG_INFO, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); } return $str2; } else if (is_array($str) ) { foreach($str as $key => $value) { if ($how == 3) { $key2 = str_replace( ['\\', "'", "\x00", "\x1a", '`', '<', '>'], ['\\\\', "\\'", '-', '-', '\\`', '<', '>'], $key, $occ); } else { $key2 = str_replace( ['\\', "'", '"', "\x0d", "\x0a", "\x00", "\x1a", '`', '<', '>'], ['\\\\', "\\'", '\\"', '-', '-', '-', '-', '`', '<', '>'], $key, $occ); } if ($occ) { unset($str[$key]); $nfw_['incidentID'] = NinjaFirewall_log::write( 'Sanitising user input', "$msg: $key", NFWLOG_INFO, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); } $str[$key2] = nfw_sanitise($value, $how, $msg); } return $str; } } // ===================================================================== 2023-05-16 // Block the user and display a message. function nfw_block() { if ( defined('NFW_STATUS') ) { return; } global $nfw_; if (! empty( $nfw_['nfw_options']['debug'] ) ) { return; } $http_codes = [ 400 => '400 Bad Request', 403 => '403 Forbidden', 404 => '404 Not Found', 406 => '406 Not Acceptable', 418 => "418 I'm a teapot", 500 => '500 Internal Server Error', 503 => '503 Service Unavailable' ]; if (! isset( $http_codes[$nfw_['nfw_options']['ret_code']] ) ) { $nfw_['nfw_options']['ret_code'] = 403; } if ( empty( $nfw_['incidentID'] ) ) { $nfw_['incidentID'] = '000000'; } $tmp = str_replace( '%%NUM_INCIDENT%%', $nfw_['incidentID'], base64_decode( $nfw_['nfw_options']['blocked_msg'] ) ); if ( isset( $nfw_['nfw_options']['logo'] ) ) { $tmp = str_replace( '%%NINJA_LOGO%%', "<img alt='NinjaFirewall' src='{$nfw_['nfw_options']['logo']}' />", $tmp ); } $tmp = str_replace('%%REM_ADDRESS%%', NFW_REMOTE_ADDR, $tmp ); NinjaFirewall_session::delete(); if (! headers_sent() ) { header("HTTP/1.1 {$http_codes[$nfw_['nfw_options']['ret_code']]}" ); header("Status: {$http_codes[$nfw_['nfw_options']['ret_code']]}" ); header('Pragma: no-cache'); header('Cache-Control: no-cache, no-store, must-revalidate'); header('Expires: 0'); } echo "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head>". "<title>NinjaFirewall {$http_codes[$nfw_['nfw_options']['ret_code']]}</title>". "<style>body{font-family:sans-serif;font-size:13px;color:#000;}</style>". "<meta http-equiv='Content-Type' content='text/html; charset=utf-8'></head>". "<body bgcolor='white'>$tmp</body></html>"; exit; } // ===================================================================== 2023-05-16 // Return the time using hrtime (PHP >= 7.3) or microtime. function nfw_fc_metrics( $action = 'start') { if ( function_exists('hrtime') ) { $metrics = 'hrtime'; } else { $metrics = 'microtime'; } // Start the chrono if ( $action == 'start') { return $metrics(true); } global $nfw_; if ( empty( $nfw_['fw_starttime'] ) ) { return 0; } // Stop the chrono and return the formatted elapsed time if ( $metrics == 'hrtime') { return number_format( ( $metrics(true) - $nfw_['fw_starttime'] ) / 1000000000, 5 ); } else { return number_format( $metrics(true) - $nfw_['fw_starttime'], 5 ); } } // ===================================================================== function nfw_bfd($where) { if ( defined('NFW_STATUS') ) { return; } global $nfw_; $bf_conf_dir = $nfw_['log_dir'] . '/cache'; if (! is_file($bf_conf_dir . '/bf_conf.php') ) { return; } $now = time(); require($bf_conf_dir . '/bf_conf.php'); if ( empty($bf_enable) ) { return; } if ( $where == 2 && empty($bf_xmlrpc) ) { return; } // NinjaFirewall <= 3.4.2: if (! isset( $auth_msgtxt ) ) { $auth_msgtxt = $auth_msg; $b64 = 0; // NinjaFirewall > 3.4.2: } else { $b64 = 1; } // NinjaFirewall < 3.5: if (! isset( $bf_allow_bot ) ) { $bf_allow_bot = 0; } if (! isset( $bf_type ) ) { $bf_type = 0; } if ( $where == 1 && $bf_allow_bot == 0 ) { nfw_is_bot( 'wp-login.php' ); } if ( $where == 1 && isset( $_REQUEST['action'] ) && in_array( $_REQUEST['action'], ['postpass', 'logout', 'lostpassword', 'retrievepassword', 'resetpass', 'rp', 'register', 'confirmaction'] ) ) { return; } if ( $bf_enable == 2 ) { nfw_check_auth($auth_name, $auth_pass, $auth_msgtxt, $bf_rand, $b64, $bf_allow_bot, $bf_type, $captcha_text, $bf_nosig); return; } if ( is_file($bf_conf_dir . '/bf_blocked' . $where . $_SERVER['SERVER_NAME'] . $bf_rand) ) { $mtime = filemtime( $bf_conf_dir . '/bf_blocked' . $where . $_SERVER['SERVER_NAME'] . $bf_rand ); if ( ($now - $mtime) < $bf_bantime * 60 ) { nfw_check_auth($auth_name, $auth_pass, $auth_msgtxt, $bf_rand, $b64, $bf_allow_bot, $bf_type, $captcha_text, $bf_nosig); return; } else { @unlink($bf_conf_dir . '/bf_blocked' . $where . $_SERVER['SERVER_NAME'] . $bf_rand); } } if ( strpos($bf_request, $_SERVER['REQUEST_METHOD']) === false ) { return; } if ( is_file($bf_conf_dir . '/bf_' . $where . $_SERVER['SERVER_NAME'] . $bf_rand ) ) { $tmp_log = file( $bf_conf_dir . '/bf_' . $where . $_SERVER['SERVER_NAME'] . $bf_rand, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ( count( $tmp_log) >= $bf_attempt ) { if ( ($tmp_log[count($tmp_log) - 1] - $tmp_log[count($tmp_log) - $bf_attempt]) <= $bf_maxtime ) { $bfdh = fopen( $bf_conf_dir . '/bf_blocked' . $where . $_SERVER['SERVER_NAME'] . $bf_rand, 'w'); fclose( $bfdh ); unlink( $bf_conf_dir . '/bf_' . $where . $_SERVER['SERVER_NAME'] . $bf_rand ); $nfw_['nfw_options']['ret_code'] = '401'; if ($where == 1) { $where = 'wp-login.php'; } else { $where = 'XML-RPC API'; } if ( $bf_type == 0 ) { $nfw_['incidentID'] = NinjaFirewall_log::write( 'Brute-force attack detected on ' . $where, 'enabling HTTP authentication for ' . $bf_bantime . 'mn', NFWLOG_CRITICAL, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); } else { $nfw_['incidentID'] = NinjaFirewall_log::write( 'Brute-force attack detected on ' . $where, 'enabling CAPTCHA for ' . $bf_bantime . 'mn', NFWLOG_CRITICAL, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); } /** * Write to the AUTH log. */ if (! empty( $bf_authlog ) ) { if (! defined('NFW_REMOTE_ADDR') ) { NinjaFirewall_IP::check_ip( $nfw_['nfw_options'] ); } if ( defined('LOG_AUTHPRIV') ) { $tmp = LOG_AUTHPRIV; } else { $tmp = LOG_AUTH; } @ openlog('ninjafirewall', LOG_NDELAY|LOG_PID, $tmp); @ syslog(LOG_INFO, 'Possible brute-force attack from '. NFW_REMOTE_ADDR . ' on '. $_SERVER['SERVER_NAME'] .' ('. $where .'). Blocking access for ' . $bf_bantime . 'mn.'); @ closelog(); } nfw_check_auth($auth_name, $auth_pass, $auth_msgtxt, $bf_rand, $b64, $bf_allow_bot, $bf_type, $captcha_text, $bf_nosig); return; } } $mtime = filemtime( $bf_conf_dir . '/bf_' . $where . $_SERVER['SERVER_NAME'] . $bf_rand ); if ( ($now - $mtime) > $bf_bantime * 60 ) { unlink( $bf_conf_dir . '/bf_' . $where . $_SERVER['SERVER_NAME'] . $bf_rand ); } } @file_put_contents($bf_conf_dir . '/bf_' . $where . $_SERVER['SERVER_NAME'] . $bf_rand, $now . "\n", FILE_APPEND | LOCK_EX); } // ===================================================================== 2023-05-16 // Block the request if a bot is detected. function nfw_is_bot( $block = '') { global $nfw_; if ( empty( $_SERVER['HTTP_ACCEPT'] ) || empty( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) || empty( $_SERVER['HTTP_USER_AGENT'] ) || stripos( $_SERVER['HTTP_USER_AGENT'], 'Mozilla') === FALSE ) { if (! empty( $block ) ) { // Whitelist server IP and private addresses calling admin-ajax.php if ( $block == 'admin-ajax.php') { if ( NFW_REMOTE_ADDR == $_SERVER['SERVER_ADDR'] || NFW_REMOTE_ADDR_PRIVATE == true ) { return true; } $block = 'Blocked access to admin-ajax.php'; // No whitelist needed for the login page: } else { $block = 'Blocked access to the login page'; } header('HTTP/1.0 404 Not Found'); header('Pragma: no-cache'); header('Cache-Control: no-cache, no-store, must-revalidate'); header('Expires: 0'); $nfw_['nfw_options']['ret_code'] = '404'; $nfw_['incidentID'] = NinjaFirewall_log::write( $block, 'bot detection is enabled', NFWLOG_MEDIUM, 0, $nfw_['nfw_options'], $nfw_['log_dir'] ); NinjaFirewall_session::delete(); exit('404 Not Found'); } return true; } return false; } // ===================================================================== function nfw_check_auth( $auth_name, $auth_pass, $auth_msgtxt, $bf_rand, $b64, $bf_allow_bot, $bf_type, $captcha_text, $bf_nosig ) { if ( defined('NFW_STATUS') ) { return; } // Prevent favicon.ico 302 redirection to the login page // due to plugins that do not handle well the login page access: if ( isset( $_GET['redirect_to'] ) && strpos( $_GET['redirect_to'], 'favicon.ico' ) !== FALSE ) { exit; } NinjaFirewall_session::start(); global $nfw_; $nfw_bfd = NinjaFirewall_session::read('nfw_bfd'); if ( isset( $nfw_bfd ) && $nfw_bfd == $bf_rand ) { return; } if ( $bf_type == 0 ) { // Password protection: if (! empty($_REQUEST['u']) && ! empty($_REQUEST['p']) ) { if ( $_REQUEST['u'] === $auth_name && sha1($_REQUEST['p']) === $auth_pass ) { NinjaFirewall_session::write( ['nfw_bfd' => $bf_rand ] ); return; } } } else { // Make sure the GD extension is loaded if ( function_exists( 'gd_info' ) ) { // Captcha protection $nfw_bfd_c = NinjaFirewall_session::read('nfw_bfd_c'); if (! empty( $_REQUEST['c'] ) && isset( $nfw_bfd_c ) ) { if ( $nfw_bfd_c == strtolower( $_REQUEST['c'] ) ) { NinjaFirewall_session::write( ['nfw_bfd' => $bf_rand ] ); NinjaFirewall_session::delete('nfw_bfd_c'); return; } } } else { // Return in no GD extension: return; } } NinjaFirewall_session::delete(); if ( $b64 ) { $auth_msgtxt = base64_decode( $auth_msgtxt ); } header('HTTP/1.0 401 Unauthorized'); header('X-Frame-Options: SAMEORIGIN'); header('Pragma: no-cache'); header('Cache-Control: no-cache, no-store, must-revalidate'); header('Expires: 0'); if ( empty( $bf_nosig ) ) { $bf_nosig = 'Brute-force protection by NinjaFirewall'; } else { $bf_nosig = ''; } if ( $bf_type == 0 ) { $message = '<html><head><title>'. $bf_nosig .'</title><link rel="stylesheet" href="./wp-includes/css/buttons.min.css" type="text/css"><link rel="stylesheet" href="./wp-admin/css/login.min.css" type="text/css"><link rel="stylesheet" href="./wp-admin/css/forms.min.css" type="text/css"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body class="login wp-core-ui" style="color:#444"><div id="login"><center><h2>' . $auth_msgtxt . '</h2><form method="post"><label>'. $bf_nosig .'</label><br><br><p><input class="input" type="text" name="u" placeholder="Username" autofocus></p><p><input class="input" type="password" name="p" placeholder="Password"></p><p align="right"><input type="submit" value="Login Page »" class="button-secondary"></p><input type="hidden" name="reauth" value="1"></form></center></div></body></html>'; } else { $captcha = nfw_get_captcha(); if ( $captcha === false ) { return; } $message = '<html><head><title>'. $bf_nosig .'</title><link rel="stylesheet" href="./wp-includes/css/buttons.min.css" type="text/css"><link rel="stylesheet" href="./wp-admin/css/login.min.css" type="text/css"><link rel="stylesheet" href="./wp-admin/css/forms.min.css" type="text/css"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body class="login wp-core-ui" style="color:#444"><div id="login"><center><form method="post"><p><label>'. base64_decode( $captcha_text ) .'</label></p><br><p>' . $captcha . '</p><p><input class="input" type="text" name="c" autofocus></p><p align="right"><input type="submit" value="Login Page »" class="button-secondary"></p><input type="hidden" name="reauth" value="1"></form><br><label>'. $bf_nosig .'</label></center></div></body></html>'; } if ( $bf_allow_bot == 0 ) { if ( @ini_set('zlib.output_compression','Off') !== false ) { header('Content-Encoding: gzip'); echo gzencode( $message, 1 ); exit; } } header('Content-Type: text/html; charset=utf-8'); echo $message; exit; } // ===================================================================== function nfw_get_captcha() { if (! function_exists( 'imagettftext' ) ) { echo "<div id='login_error'>NinjaFirewall error: PHP imagettftext() function doesn't exist, the captcha can't be displayed. Make sure PHP is compiled with freetype support (--with-freetype-dir=DIR).</div>"; return false; } NinjaFirewall_session::start(); $characters = 'AaBbCcDdEeFfGgHhiIJjKkLMmNnPpRrSsTtUuVvWwXxYyZz123456789'; $captcha = ''; while( strlen( $captcha ) < 5 ) { $captcha .= substr( $characters, mt_rand() % strlen( $characters ), 1 ); } // Background image with dimensions $image = imagecreate( 200, 60 ); // Background color: imagecolorallocate( $image, 255, 255, 255 ); // Text color: $text_color = imagecolorallocate( $image, 77, 77, 77 ); // Font: global $nfw_; if ( is_file( "{$nfw_['log_dir']}/font.ttf" ) ) { imagettftext( $image, 35, 0, 15, 45, $text_color, "{$nfw_['log_dir']}/font.ttf", $captcha ); } else { imagettftext( $image, 35, 0, 15, 45, $text_color, __DIR__ . '/share/font.ttf', $captcha ); } ob_start(); imagepng( $image ); $img_content = ob_get_contents(); ob_end_clean(); $res = '<img src="data:image/png;base64,'. base64_encode( $img_content ) .'" />'; NinjaFirewall_session::write( ['nfw_bfd_c' => strtolower( $captcha ) ] ); return $res; } // ===================================================================== 2023-05-16 // Handle HTTP response headers. function nfw_response_headers() { if ( defined('NFW_CUSTHEADERS') ) { nfw_custom_headers(); } if (! defined('NFW_RESHEADERS') ) { return; } $NFW_RESHEADERS = NFW_RESHEADERS; // NFW_RESHEADERS: // 0000000000 // ||||||||||_ SameSite[0-2] // |||||||||__ Referrer-Policy [0-8] // ||||||||___ Content-Security-Policy (backend) [0-1] // |||||||____ Content-Security-Policy (frontend) [0-1] // ||||||_____ Strict-Transport-Security (includeSubDomains) [0-1] // |||||______ Strict-Transport-Security [0-4] // ||||_______ X-XSS-Protection [0-3] // |||________ X-Frame-Options [0-2] // ||_________ X-Content-Type-Options [0-1] // |__________ HttpOnly cookies [0-1] // Force HttpOnly and/or SameSite cookie if (! empty( $NFW_RESHEADERS[0] ) || ! empty( $NFW_RESHEADERS[9] ) ) { $rewrite = []; // Parse all response headers foreach (headers_list() as $header) { // Ignore it if it is not a cookie if ( strpos( $header, 'Set-Cookie:' ) === false ) { continue; } $extra = ''; // HttpOnly if (! empty( $NFW_RESHEADERS[0] ) ) { // Does it have the HttpOnly flag on if ( stripos( $header, '; HttpOnly') === false) { $extra .= '; HttpOnly'; } } // SameSite if (! empty( $NFW_RESHEADERS[9] ) ) { // Lax if ( $NFW_RESHEADERS[9] == 1 && stripos( $header, '; SameSite=Lax' ) === false ) { $extra .= '; SameSite=Lax'; // Strict } elseif ( $NFW_RESHEADERS[9] == 2 && stripos( $header, '; SameSite=Strict' ) === false ) { $extra .= '; SameSite=Strict'; } } // Save cookie $rewrite[] = "{$header}{$extra}"; } // Shall we rewrite cookies if (! empty( $rewrite ) ) { // Remove all original cookies header_remove('Set-Cookie'); foreach( $rewrite as $cookie ) { // Inject ours instead header( $cookie, false ); } } } if (! empty( $NFW_RESHEADERS[1] ) ) { header('X-Content-Type-Options: nosniff'); } if (! empty( $NFW_RESHEADERS[2] ) ) { if ($NFW_RESHEADERS[2] == 1) { header('X-Frame-Options: SAMEORIGIN'); } else { header('X-Frame-Options: DENY'); } } if ( empty( $NFW_RESHEADERS[3] ) ) { header('X-XSS-Protection: 0'); } elseif ( $NFW_RESHEADERS[3] == 1 ) { header('X-XSS-Protection: 1; mode=block'); } elseif ( $NFW_RESHEADERS[3] == 2 ) { header('X-XSS-Protection: 1'); } if (! empty( $NFW_RESHEADERS[6] ) && strpos($_SERVER['SCRIPT_NAME'], '/wp-admin/') === FALSE ) { header('Content-Security-Policy: ' . CSP_FRONTEND_DATA); } if (! empty( $NFW_RESHEADERS[7] ) && strpos($_SERVER['SCRIPT_NAME'], '/wp-admin/') !== FALSE ) { header('Content-Security-Policy: ' . CSP_BACKEND_DATA); } if (! empty( $NFW_RESHEADERS[8] ) ) { if ( $NFW_RESHEADERS[8] == 1 ) { $rf = 'no-referrer'; } elseif ( $NFW_RESHEADERS[8] == 2 ) { $rf = 'no-referrer-when-downgrade'; } elseif ( $NFW_RESHEADERS[8] == 3 ) { $rf = 'origin'; } elseif ( $NFW_RESHEADERS[8] == 4 ) { $rf = 'origin-when-cross-origin'; } elseif ( $NFW_RESHEADERS[8] == 5 ) { $rf = 'strict-origin'; } elseif ( $NFW_RESHEADERS[8] == 6 ) { $rf = 'strict-origin-when-cross-origin'; } elseif ( $NFW_RESHEADERS[8] == 7 ) { $rf = 'same-origin'; } else { $rf = 'unsafe-url'; } header("Referrer-Policy: $rf"); } // Stop here if no more headers if ( empty($NFW_RESHEADERS[4] ) ) { return; } // We don't send HSTS headers over HTTP if (! defined('NFW_IS_HTTPS') ) { nfw_is_https(); } if ( NFW_IS_HTTPS == false ) { return; } if ($NFW_RESHEADERS[4] == 1) { // 1 month $max_age = 'max-age=2628000'; } elseif ($NFW_RESHEADERS[4] == 2) { // 6 months $max_age = 'max-age=15768000'; } elseif ($NFW_RESHEADERS[4] == 3) { // 12 months $max_age = 'max-age=31536000'; } elseif ($NFW_RESHEADERS[4] == 4) { // Send an empty max-age to signal the UA to // cease regarding the host as a known HSTS Host $max_age = 'max-age=0'; } else { // 24 months $max_age = 'max-age=63072000'; } if (! empty( $NFW_RESHEADERS[5] ) ) { if ( $NFW_RESHEADERS[5] == 1 ) { $max_age .= '; includeSubDomains'; } elseif ( $NFW_RESHEADERS[5] == 2 ) { $max_age .= '; preload'; } else { $max_age .= '; includeSubDomains; preload'; } } header('Strict-Transport-Security: '. $max_age); } // ===================================================================== 2023-05-16 function nfw_custom_headers() { $headers = json_decode( NFW_CUSTHEADERS, true ); if (! empty( $headers ) ) { foreach( $headers as $key => $value ) { header( "$key: $value" ); } } } // ===================================================================== // EOF